package com.dai.rpc.proxy;

import com.dai.rpc.annotation.MyMapping;
import com.dai.rpc.annotation.MyReference;
import com.dai.rpc.exceptions.MyRpcException;
import com.dai.rpc.factory.SingletonFactory;
import com.dai.rpc.message.RpcRequest;
import com.dai.rpc.message.RpcResponse;
import com.dai.rpc.netty.client.NettyClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.client.RestTemplate;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class MyRpcClientProxy implements InvocationHandler {

    private MyReference myReference;
    private NettyClient nettyClient;

    public MyRpcClientProxy(MyReference myReference,NettyClient nettyClient) {
        this.myReference = myReference;
        this.nettyClient = nettyClient;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        //log.info("执行了代理逻辑。。。rpc服务消费方发起了调用...invoke调用");

        // 组装RpcRequest，并发送
       /* String host = myReference.host();
        int port = myReference.port();*/

        String version = myReference.version();
        RpcRequest rpcRequest = RpcRequest.builder().
                interfaceName(method.getDeclaringClass().getName())
                .paramTypes(method.getParameterTypes())
                .requestId(UUID.randomUUID().toString())
                .version(version)
                .methodName(method.getName())
                .parameters(args)
                .build();
        // 创建Netty客户端，发起调用
        Object o = nettyClient.sendRequest(rpcRequest);
        RpcResponse<Object> response = null;

        CompletableFuture<RpcResponse<Object>> future = (CompletableFuture<RpcResponse<Object>>) o;
        response = future.get();
        if(response == null){
            throw new MyRpcException("服务调用失败!");
        }
        // 判断请求Id是否一致
        if(!rpcRequest.getRequestId().equals(response.getRequestId())){
            throw new MyRpcException("响应结果和请求不一致!");
        }

        return response.getData();
    }

    public <T> T getProxy(Class<T> interfaceClass) {
        return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[]{interfaceClass}, this);
    }
}
